home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Plus / Multimedia Plus with ClearVue Version 10-94 (Knowledge Media Inc.).ISO / dos / aud_cnvt / sox7dos / wav.c < prev   
Text File  |  1993-02-11  |  4KB  |  194 lines

  1. /*
  2.  * April 15, 1992
  3.  * Copyright 1992 Rick Richardson
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11.  /* TODO: FIX 16 bits samples to be signed instead of unsigned */
  12.  
  13. /*
  14.  * Windows 3.0 .wav format driver
  15.  */
  16.  
  17. #include "st.h"
  18.  
  19. /* Private data for .wav file */
  20. typedef struct wavstuff {
  21.     long    samples;
  22. } *wav_t;
  23.  
  24. IMPORT float volume, amplitude;
  25. IMPORT long summary, verbose;
  26.  
  27. /*
  28.  * Do anything required before you start reading samples.
  29.  * Read file header. 
  30.  *    Find out sampling rate, 
  31.  *    size and style of samples, 
  32.  *    mono/stereo/quad.
  33.  */
  34. wavstartread(ft) 
  35. ft_t ft;
  36. {
  37.     wav_t    wav = (wav_t) ft->priv;
  38.     char    magic[4];
  39.     long    len;
  40.  
  41.     /* If you need to seek around the input file. */
  42.     if (0 && ! ft->seekable)
  43.         fail(".wav input file must be a file, not a pipe");
  44.  
  45.     fread(magic, 4, 1, ft->fp);
  46.     if (strncmp("RIFF", magic, 4))
  47.         fail("Not a RIFF file");
  48.  
  49.     len = rllong(ft);
  50.  
  51.     fread(magic, 4, 1, ft->fp);
  52.     if (strncmp("WAVE", magic, 4))
  53.         fail("Not a WAVE file");
  54.  
  55.     fread(magic, 4, 1, ft->fp);
  56.     if (strncmp("fmt ", magic, 4))
  57.         fail("Missing fmt spec");
  58.  
  59.     len = rllong(ft);
  60.     switch (rlshort(ft))
  61.     {
  62.     case 1:        ft->info.style = UNSIGNED; break;
  63.     default:    fail("Don't understand format");
  64.     }
  65.     ft->info.channels = rlshort(ft);
  66.     ft->info.rate = rllong(ft);
  67.     rllong(ft);    /* Average bytes/second */
  68.     rlshort(ft);    /* Block align */
  69.     switch (rlshort(ft))
  70.     {
  71.     case 8:        ft->info.size = BYTE; break;
  72.     case 16:    ft->info.size = WORD; break;
  73.     case 32:    ft->info.size = LONG; break;
  74.     default:    fail("Don't understand size");
  75.     }
  76.     len -= 16;
  77.     while (len) getc(ft->fp);
  78.  
  79.     fread(magic, 4, 1, ft->fp);
  80.     if (strncmp("data", magic, 4))
  81.         fail("Missing data portion");
  82.  
  83.     wav->samples = rllong(ft);
  84. }
  85.  
  86. /*
  87.  * Read up to len samples from file.
  88.  * Convert to signed longs.
  89.  * Place in buf[].
  90.  * Return number of samples read.
  91.  */
  92.  
  93. wavread(ft, buf, len) 
  94. ft_t ft;
  95. long *buf, len;
  96. {
  97.     wav_t    wav = (wav_t) ft->priv;
  98.     int    done;
  99.  
  100.     if (len > wav->samples) len = wav->samples;
  101.     if (len == 0) return 0;
  102.     done = rawread(ft, buf, len);
  103.     wav->samples -= len;
  104.     return done;
  105. }
  106.  
  107. /*
  108.  * Do anything required when you stop reading samples.  
  109.  * Don't close input file! 
  110.  */
  111. wavstopread(ft) 
  112. ft_t ft;
  113. {
  114. }
  115.  
  116. wavstartwrite(ft) 
  117. ft_t ft;
  118. {
  119.     wav_t    wav = (wav_t) ft->priv;
  120.     int    littlendian = 0;
  121.     char    *endptr;
  122.  
  123.     if (! ft->seekable)
  124.         fail("Output .wav file must be a file, not a pipe");
  125.  
  126.     endptr = (char *) &littlendian;
  127.     *endptr = 1;
  128.     if (!littlendian) ft->swap = 1;
  129.  
  130.     wav->samples = 0;
  131.     wavwritehdr(ft);
  132. }
  133.  
  134. wavwritehdr(ft) 
  135. ft_t ft;
  136. {
  137.     wav_t    wav = (wav_t) ft->priv;
  138.     int    samsize;
  139.     long    datasize;
  140.  
  141.     switch (ft->info.size)
  142.     {
  143.     case BYTE:    samsize = 8; ft->info.style = UNSIGNED; break;
  144.     case WORD:    samsize = 16; ft->info.style = SIGN2; break;
  145.     default:
  146.     case LONG:    ft->info.size = LONG; ft->info.style = SIGN2; 
  147.             samsize = 32; break;
  148.     }
  149.     
  150.  
  151.     datasize = samsize/8 * ft->info.channels * wav->samples;
  152.  
  153.     fputs("RIFF", ft->fp);
  154.     wllong(ft, datasize + 8+16+12);    /* Waveform chunk size: FIXUP(4) */
  155.     fputs("WAVE", ft->fp);
  156.     fputs("fmt ", ft->fp);
  157.     wllong(ft, (long)16);        /* fmt chunk size */
  158.     wlshort(ft, 1);            /* FormatTag: WAVE_FORMAT_PCM */
  159.     wlshort(ft, ft->info.channels);
  160.     wllong(ft, (long)ft->info.rate);    /* SamplesPerSec */
  161.                     /* Average Bytes/sec */
  162.     wllong(ft, ((long)ft->info.rate * ft->info.channels * samsize + 7) / 8);
  163.                     /* nBlockAlign */
  164.     wlshort(ft, (ft->info.channels * samsize + 7) / 8);
  165.     wlshort(ft, samsize);        /* BitsPerSample */
  166.     
  167.     fputs("data", ft->fp);
  168.     wllong(ft, datasize);        /* data chunk size: FIXUP(40) */
  169. }
  170.  
  171. wavwrite(ft, buf, len) 
  172. ft_t ft;
  173. long *buf, len;
  174. {
  175.     wav_t    wav = (wav_t) ft->priv;
  176.  
  177.     wav->samples += len * ft->info.size;
  178.     rawwrite(ft, buf, len);
  179. }
  180.  
  181. void
  182. wavstopwrite(ft) 
  183. ft_t ft;
  184. {
  185.     /* All samples are already written out. */
  186.     /* If file header needs fixing up, for example it needs the */
  187.      /* the number of samples in a field, seek back and write them here. */
  188.     if (!ft->seekable)
  189.         return;
  190.     if (fseek(ft->fp, 0L, 0) != 0)
  191.         fail("Can't rewind output file to rewrite .wav header.");
  192.     wavwritehdr(ft);
  193. }
  194.